﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ams.Mvc.Bootstrap.Annotations
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Web.Mvc;

    namespace MerchManagement.Web.Helpers
    {
        /// <summary>
        /// Allows you specify a breadcrumb hierarchy. Used by @Html.Breadcrumb() method.
        /// </summary>
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
        public class BreadcrumbAttribute : Attribute
        {
            /// <summary>
            /// Initializes a new instance of the <see cref="BreadcrumbAttribute"/> class.
            /// </summary>
            public BreadcrumbAttribute()
            {
                RouteValueMap = new List<BreadcrumbRouteValueMapAttribute>();
            }

            /// <summary>
            /// Gets or sets the text displayed in the breadcrumb for the action this attribute is applied to.
            /// </summary>
            /// <value>The text displayed in the breadcrumb for this action.</value>
            public virtual string Text { get; set; }

            /// <summary>
            /// Gets or sets the action that is the breadcrumb parent for the action this attribute is applied to.
            /// </summary>
            /// <value> The action that is the breadcrumb parent for this action.</value>
            public virtual string ParentAction { get; set; }

            /// <summary>
            /// Gets or sets the controller the <see cref="ParentAction"/> belongs to. When this is not set, it will default to current controller. 
            /// </summary>
            /// <value> The parent controller. </value>
            public virtual string ParentController { get; set; }

            /// <summary>
            /// Gets or sets the route value map.
            /// </summary>
            /// <value>The route value map.</value>
            public virtual List<BreadcrumbRouteValueMapAttribute> RouteValueMap { get; set; }

            public BreadcrumbAttribute GetParentBreadcrumbAttribute(ControllerBase controller)
            {
                if (String.IsNullOrWhiteSpace(ParentAction) && String.IsNullOrWhiteSpace(ParentController))
                {
                    return null;
                }

                var parentAction = String.IsNullOrWhiteSpace(ParentAction) ? "Index" : ParentAction;
                if (!String.IsNullOrWhiteSpace(ParentController))
                {
                    var parentController = controller.GetType().Namespace + "." + ParentController + "Controller";
                    var parentControllerType = controller.GetType().Assembly.GetType(parentController);
                    var method = parentControllerType.GetMethod(parentAction);
                    return GetBreadcrumbAttribute(method);
                }
                return GetBreadcrumbAttribute(controller, parentAction);
            }

            public static BreadcrumbAttribute GetBreadcrumbAttribute(ControllerBase controller, string action)
            {
                var method = controller.GetType().GetMethods().FirstOrDefault(i => i.Name.Equals(action, StringComparison.InvariantCultureIgnoreCase));
                return GetBreadcrumbAttribute(method);
            }

            public static BreadcrumbAttribute GetBreadcrumbAttribute(MethodInfo method)
            {
                var breadcrumbAttribute = method.GetCustomAttributes(true).OfType<BreadcrumbAttribute>().FirstOrDefault();
                var attribute = breadcrumbAttribute ?? new BreadcrumbAttribute { Text = method.Name };
                attribute.RouteValueMap = method.GetCustomAttributes(true).OfType<BreadcrumbRouteValueMapAttribute>().ToList();
                return attribute;
            }
        }

        [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
        public class BreadcrumbRouteValueMapAttribute : Attribute
        {
            public virtual string ParentAction { get; set; }
            public virtual string RouteParameter { get; set; }
            public virtual string ParentRouteParameter { get; set; }
        }
    }
}
